package com.mtiiot.fstask.task;

import com.enterprisedt.net.ftp.FTPException;
import com.enterprisedt.net.ftp.FTPFile;
import com.enterprisedt.net.ftp.FileTransferClient;
import com.enterprisedt.net.ftp.FileTransferOutputStream;
import com.mtiiot.fstask.bean.FtpBean;
import com.mtiiot.fscore.bean.MetadataInfo;
import com.mtiiot.fscore.inter1.LogService1;
import com.mtiiot.fscore.inter1.RedisService1;
import com.mtiiot.fscore.utils.LogLevel;
import com.mtiiot.fscore.utils.SysName;
import com.mtiiot.fstask.esdao.BaseElasticsearch;
import com.mtiiot.fstask.utils.Contants;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by lcy on 16-9-8.
 */
public class FtpThreadTask implements Runnable{
    private static final Logger logger = LogManager.getLogger(FtpThreadTask.class);
    private String ftpContent;
    private LogService1 logService1;
    private RedisService1 redisService1;
    private BaseElasticsearch baseElasticsearch;
    private int timeout;

    public FtpThreadTask(String ftpContent, LogService1 logService1, RedisService1 redisService1, int timeout) {
        this.ftpContent = ftpContent;
        this.logService1 = logService1;
        this.redisService1 = redisService1;
        this.timeout = timeout;
    }

    public FtpThreadTask(String ftpContent, LogService1 logService1, RedisService1 redisService1, int timeout,BaseElasticsearch baseElasticsearch) {
        this.ftpContent = ftpContent;
        this.logService1 = logService1;
        this.redisService1 = redisService1;
        this.timeout = timeout;
        this.baseElasticsearch=baseElasticsearch;
    }
    @Override
    public void run() {
        //System.out.println("开启一个线程");
        FileTransferClient ftp = null;
        FileTransferOutputStream ffos=null;
        FtpBean fb=null;
        ObjectMapper mapper = new ObjectMapper();
        String metaDataId=null;
        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            try{
                fb = mapper.readValue(ftpContent, FtpBean.class);
            }catch (Exception exx){
                redisService1.lpush(new MetadataInfo("",Contants.SYS_ID_FS,Contants.FSTASK_HOST),Contants.FTP_REDISKEY_001,ftpContent);
                return;
            }
            try{
                metaDataId=fb.getMetaDataId();
                if(metaDataId!=null){
                    Map<String,String> m=new HashMap<String, String>();
                    m.put(Contants.FTP_TRAN_TIME_FIELD_START,sdf.format(new Date()));
                    baseElasticsearch.updateIndex(Contants.INDEX_METADATA,Contants.TYPE_METADATA_FTP,metaDataId,m);
                }
            }catch (Exception exxx){
                logService1.sendLog(new MetadataInfo(Contants.SYS_ID_FS,Contants.FSTASK_HOST,Contants.MODULE_FSTASK, "FtpTask", "execute"),LogLevel.ERROR,"ftp transfer start time in es exception",exxx.getMessage());
                logger.error(exxx.getMessage(), exxx);
            }

            //文件写入ftp服务器,连续3次不成功的话,就写error文件夹并短信通知
            ftp = new FileTransferClient();
            // set remote host
            ftp.setRemoteHost(fb.getHost());
            ftp.setUserName(fb.getUserName());
            ftp.setPassword(fb.getPassword());
            ftp.setRemotePort(fb.getPort());
            ftp.setTimeout(timeout);
            byte[] files = null;
            if (fb.getFiles() != null) {
                files = fb.getFiles();
            } else if (fb.getContent() != null && !fb.getContent().equals("")) {
                files = fb.getContent().getBytes("utf-8");
            } else {
                throw new Exception("文件为空!不能往ftp服务上传文件");
            }
            if (fb.getRemoteFileName() == null || fb.getRemoteFileName().equals("")) {
                throw new Exception("待上传文件名为空!不能往ftp服务上传文件");
            }
            ftp.connect();
            if (fb.getRemoteFilePath() != null && !fb.getRemoteFilePath().equals("")) {
                FTPFile[] ftpFiles=ftp.directoryList();
                boolean isExist=false;
                for(FTPFile ftpFile:ftpFiles){
                    if(ftpFile.getName().equals(fb.getRemoteFilePath())){
                        isExist=true;
                        break;
                    }
                }
                if(!isExist){
                    ftp.createDirectory(fb.getRemoteFilePath());
                }
                ftp.changeDirectory(fb.getRemoteFilePath());
            }
            ffos = ftp.uploadStream(fb.getRemoteFileName());
            ffos.write(files);
            ffos.flush();
        } catch (Exception ex) {
            if(fb.getReTryTime()<3){
                fb.setReTryTime(fb.getReTryTime()+1);
                try {
                    redisService1.lpush(new MetadataInfo("",Contants.SYS_ID_FS,Contants.FSTASK_HOST),Contants.FTP_REDISKEY_001,mapper.writeValueAsString(fb));
                } catch (IOException e) {
                    logService1.sendLog(new MetadataInfo(Contants.SYS_ID_FS,Contants.FSTASK_HOST,Contants.MODULE_FSTASK, "FtpTask", "execute"),LogLevel.ERROR,"redis lpush exception",e.getMessage());
                    logger.error(ex.getMessage(), e);
                }
            }else{
                try{
                    redisService1.lpush(new MetadataInfo("",Contants.SYS_ID_FS,Contants.FSTASK_HOST),Contants.FTP_REDISKEY_001_ERROR,mapper.writeValueAsString(fb));
                }catch (IOException e){
                    logService1.sendLog(new MetadataInfo(Contants.SYS_ID_FS,Contants.FSTASK_HOST,Contants.MODULE_FSTASK, "FtpTask", "execute"),LogLevel.ERROR,"redis lpush exception",e.getMessage());
                    logger.error(ex.getMessage(), e);
                }
                logService1.sendLog(new MetadataInfo(Contants.SYS_ID_FS,Contants.FSTASK_HOST,Contants.MODULE_FSTASK, "FtpTask", "execute"),LogLevel.ERROR," after reTry 3 Times,also failure!!",ex.getMessage());
                logger.error(ex.getMessage(), ex);
            }
        } finally {
            if(ffos!=null){
                try {
                    ffos.close();
                } catch (IOException e) {
                    logService1.sendLog(new MetadataInfo(Contants.SYS_ID_FS,Contants.FSTASK_HOST,Contants.MODULE_FSTASK, "FtpTask", "execute"),LogLevel.ERROR,"FileTransferOutputStream close exception",e.getMessage());
                    logger.error(e.getMessage(), e);
                }
            }
            if (ftp != null) {
                if (ftp.isConnected()) {
                    try {
                        ftp.disconnect();
                    } catch (Exception e) {
                        logService1.sendLog(new MetadataInfo(Contants.SYS_ID_FS,Contants.FSTASK_HOST,Contants.MODULE_FSTASK, "FtpTask", "execute"),LogLevel.ERROR,"ftp disconnect exception",e.getMessage());
                        logger.error(e.getMessage(), e);
                    }
                }
            }

            try{
                metaDataId=fb.getMetaDataId();
                if(metaDataId!=null){
                    Map<String,String> m=new HashMap<String, String>();
                    m.put(Contants.FTP_TRAN_TIME_FIELD_END,sdf.format(new Date()));
                    baseElasticsearch.updateIndex(Contants.INDEX_METADATA,Contants.TYPE_METADATA_FTP,metaDataId,m);
                }
            }catch (Exception exception){
                logService1.sendLog(new MetadataInfo(Contants.SYS_ID_FS,Contants.FSTASK_HOST,Contants.MODULE_FSTASK, "FtpTask", "execute"),LogLevel.ERROR,"ftp transfer end time in es exception",exception.getMessage());
                logger.error(exception.getMessage(), exception);
            }
        }
    }
}
